package org.icnmasjid.member.model;
// Generated Feb 5, 2008 8:40:40 AM by Hibernate Tools 3.1.0.beta4

import java.sql.Date;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.FactoryUtils;
import org.apache.commons.collections.list.LazyList;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;


/**
 * @struts.form include-all="true" extends="BaseForm"
 * @hibernate.class
 *         table="person"
 *
 */

public class Person extends org.icnmasjid.member.model.BaseObject implements java.io.Serializable {


    // Fields

    private Integer personId;
    private String firstName;
    private String lastName;
    private String gender;
    private String email;
    private String email2;
    private String phoneHome;
    private String phoneWork;
    private String phoneMobile;
    private String phoneFax;
    private Timestamp createdDate;
    private Timestamp updatedDate;
    private Date residentStartDate;
    private Boolean citizen;
    private String updatedBy;
    private String personStatus = "Active";
    private String employerName;
    private Boolean primaryPerson;
    private Date dateOfBirth;
    private Integer sourceId;
    private String sourceType;
    private Integer version = 1;
    private Integer userViewed = 0;
    private Integer userUpdated = 0;
    private Timestamp emailSent;
    private String allergies;
    private Boolean registeredToVote;
    private Boolean employerMatchesDonation;
    private String comments;
    private String rfid;

    private Set<AccessGroup> accessGroups;
    private Set<ModeOfCommunication> modeOfCommunications;
    private Set<Language> languages;
    private Set<Activity> activities;
    private Set<Profession> professions;
    private Set<Login> logins;
    private Set<Skill> skills;
    private Set<Subscription> subscriptions;
    private Set<Address> addresses = new HashSet<Address>();
    private Set<PersonSubOrgRole> personSubOrgRoles = new HashSet<PersonSubOrgRole>();
    private Set<PersonRelation> personRelations = new HashSet<PersonRelation>();
    private Set<PersonRelation> parentPersonRelations = new HashSet<PersonRelation>();
    private Set<MemberInformation> memberInformations = new HashSet<MemberInformation>();
    private Set<PersonPayment> personPayments = new HashSet<PersonPayment>();

    private String notes;
    private Date verifiedDate;
    private Boolean optInForTextMessages;


    // transient
    private Address searchAddress = new Address();
    private boolean searchPrimary = false;

    private Integer searchMemberYear;

    private boolean searchVerified = false;

    private List<Address> addressList =
    	LazyList.decorate(
    		new ArrayList<Address>(),
    		FactoryUtils.instantiateFactory(Address.class)
    	);

    // currently used for searching
    private SubOrg subOrg = new SubOrg();
    private Role role = new Role();
    // used for creating new payments
    private PersonPayment personPayment = new PersonPayment();

    private List<Integer> memberYear = new ArrayList<Integer>();

    // Constructors
	/** default constructor */
    public Person() {
    }

	/** minimal constructor */
    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    /** full constructor */
    public Person(String firstName, String lastName, String gender, String email, String email2, String phoneHome, String phoneWork, String phoneMobile, String phoneFax, Timestamp createdDate, Timestamp updatedDate, Date residentStartDate, Boolean citizen, String updatedBy, String personStatus, String employerName, Boolean primaryPerson, Date dateOfBirth, int version) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
        this.email = email;
        this.email2 = email2;
        this.phoneHome = phoneHome;
        this.phoneWork = phoneWork;
        this.phoneMobile = phoneMobile;
        this.phoneFax = phoneFax;
        this.createdDate = createdDate;
        this.updatedDate = updatedDate;
        this.residentStartDate = residentStartDate;
        this.citizen = citizen;
        this.updatedBy = updatedBy;
        this.personStatus = personStatus;
        this.employerName = employerName;
        this.primaryPerson = primaryPerson;
        this.dateOfBirth = dateOfBirth;
        this.version = version;
    }

    /** copy from another person object */
    public Person(Person p_person)
    {
        this.firstName = p_person.firstName;
        this.lastName = p_person.lastName;
        this.gender = p_person.gender;
        this.email = p_person.email;
        this.email2 = p_person.email2;
        this.phoneHome = p_person.phoneHome;
        this.phoneWork = p_person.phoneWork;
        this.phoneMobile = p_person.phoneMobile;
        this.phoneFax = p_person.phoneFax;
        this.residentStartDate = p_person.residentStartDate;
        this.citizen = p_person.citizen;
        this.personStatus = p_person.personStatus;
        this.employerName = p_person.employerName;
        this.primaryPerson = p_person.primaryPerson;
    }

    // Property accessors

	/**
     *            @hibernate.set
     *             lazy="true"
     *             cascade="all-delete-orphan"
     *             inverse="true"
     *             order-by="role_id"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.one-to-many
     *             	class="org.icnmasjid.member.model.PersonSubOrgRole"
     *
     *
     */
	public Set<PersonSubOrgRole> getPersonSubOrgRoles() {
		return personSubOrgRoles;
	}

	public void setPersonSubOrgRoles(Set<PersonSubOrgRole> personSubOrgRoles) {
		this.personSubOrgRoles = personSubOrgRoles;
	}

    /**
     *            @hibernate.set
     *             lazy="true"
     *             cascade="all-delete-orphan"
     *             inverse="true"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.one-to-many
     *             	class="org.icnmasjid.member.model.PersonRelation"
     *
     *
     */
    public Set<PersonRelation> getPersonRelations() {
		return personRelations;
	}

	public void setPersonRelations(Set<PersonRelation> personRelations) {
		this.personRelations = personRelations;
	}

	public PersonRelation getPersonRelation(Person relatedPerson) {
		if ( relatedPerson != null ) {
			for ( PersonRelation pr: getPersonRelations()) {
				if ( pr.getRelatedPerson().getPersonId().equals(relatedPerson.getPersonId())) {
					return pr;
				}
			}
		}
		return null;
	}

    public Person getPrimary() {
		for ( PersonRelation r: getParentPersonRelations() ) {
			return r.getPerson();
		}
		return null;
	}


    /**
     *            @hibernate.set
     *             lazy="true"
     *             cascade="delete"             
     *             inverse="true"
     *            @hibernate.key
     *             column="related_person_id"
     *             not-null="true"
     *            @hibernate.one-to-many
     *             	class="org.icnmasjid.member.model.PersonRelation"
     *
     *
     */
    public Set<PersonRelation> getParentPersonRelations() {
		return parentPersonRelations;
	}

	public void setParentPersonRelations(Set<PersonRelation> personRelations) {
		this.parentPersonRelations = personRelations;
	}


	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="person_activity"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="activity_id"
     *             class="org.icnmasjid.member.model.Activity"
     *
     */
    public Set<Activity> getActivities() {
		return activities;
	}

	public void setActivities(Set<Activity> activities) {
		this.activities = activities;
	}

	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="person_address"
     *             cascade="all-delete-orphan"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="add_id"
     *             class="org.icnmasjid.member.model.Address"
     *
     */
	public Set<Address> getAddresses() {
		return addresses;
	}

	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}

	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="person_language"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="language_id"
     *             class="org.icnmasjid.member.model.Language"
     *
     */
	public Set<Language> getLanguages() {
		return languages;
	}

	public void setLanguages(Set<Language> languages) {
		this.languages = languages;
	}


	/**
     *            @hibernate.set
     *             lazy="true"
     *             cascade="all-delete-orphan"
     *             inverse="true"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.one-to-many
     *             class="org.icnmasjid.member.model.Login"
     *
     */
	public Set<Login> getLogins() {
		return logins;
	}

	public void setLogins(Set<Login> logins) {
		this.logins = logins;
	}

	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="pref_person_mode_of_communication"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="mode_of_communication_id"
     *             class="org.icnmasjid.member.model.ModeOfCommunication"
     *
     */
	public Set<ModeOfCommunication> getModeOfCommunications() {
		return modeOfCommunications;
	}

	public void setModeOfCommunications(
			Set<ModeOfCommunication> modeOfCommunications) {
		this.modeOfCommunications = modeOfCommunications;
	}

	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="person_profession"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="profession_id"
     *             not-null="true"
     *             class="org.icnmasjid.member.model.Profession"
     *
     */
	public Set<Profession> getProfessions() {
		return professions;
	}

	public void setProfessions(Set<Profession> professions) {
		this.professions = professions;
	}

	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="person_skill"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="skill_id"
     *             class="org.icnmasjid.member.model.Skill"
     *
     */
	public Set<Skill> getSkills() {
		return skills;
	}

	public void setSkills(Set<Skill> skills) {
		this.skills = skills;
	}

	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="person_subscription"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="subscription_id"
     *             class="org.icnmasjid.member.model.Subscription"
     *
     */
	public Set<Subscription> getSubscriptions() {
		return subscriptions;
	}

	public void setSubscriptions(Set<Subscription> subscriptions) {
		this.subscriptions = subscriptions;
	}

    /**
     *      *            @hibernate.id
     *             generator-class="native"
     *             type="java.lang.Integer"
     *             column="person_id"
     *
     */

    public Integer getPersonId() {
        return this.personId;
    }

    public void setPersonId(Integer personId) {
        this.personId = personId;
    }
    /**
     *      *            @hibernate.property
     *             column="first_name"
     *             length="50"
     *             not-null="true"
     *
     */

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    /**
     *      *            @hibernate.property
     *             column="last_name"
     *             length="50"
     *             not-null="true"
     *
     */

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    /**
     *      *            @hibernate.property
     *             column="gender"
     *             length="1"
     *
     */

    public String getGender() {
        return this.gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
    /**
     *      *            @hibernate.property
     *             column="email"
     *             length="100"
     *
     */

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
    /**
     *      *            @hibernate.property
     *             column="email2"
     *             length="100"
     *
     */

    public String getEmail2() {
        return this.email2;
    }

    public void setEmail2(String email2) {
        this.email2 = email2;
    }
    /**
     *      *            @hibernate.property
     *             column="phone_home"
     *             length="20"
     *
     */

    public String getPhoneHome() {
        return this.phoneHome;
    }

    public void setPhoneHome(String phoneHome) {
        this.phoneHome = phoneHome;
    }
    /**
     *      *            @hibernate.property
     *             column="phone_work"
     *             length="20"
     *
     */

    public String getPhoneWork() {
        return this.phoneWork;
    }

    public void setPhoneWork(String phoneWork) {
        this.phoneWork = phoneWork;
    }
    /**
     *      *            @hibernate.property
     *             column="phone_mobile"
     *             length="20"
     *
     */

    public String getPhoneMobile() {
        return this.phoneMobile;
    }

    public void setPhoneMobile(String phoneMobile) {
        this.phoneMobile = phoneMobile;
    }
    /**
     *      *            @hibernate.property
     *             column="phone_fax"
     *             length="20"
     *
     */

    public String getPhoneFax() {
        return this.phoneFax;
    }

    public void setPhoneFax(String phoneFax) {
        this.phoneFax = phoneFax;
    }
    /**
     *      *            @hibernate.property
     *             column="created_date"
     *             length="19"
     *
     */

    public Timestamp getCreatedDate() {
        return this.createdDate;
    }

    public void setCreatedDate(Timestamp createdDate) {
        this.createdDate = createdDate;
    }
    /**
     *      *            @hibernate.property
     *             column="updated_date"
     *             length="19"
     *
     */

    public Timestamp getUpdatedDate() {
        return this.updatedDate;
    }

    public void setUpdatedDate(Timestamp updatedDate) {
        this.updatedDate = updatedDate;
    }
    /**
     *      *            @hibernate.property
     *             column="resident_start_date"
     *             length="10"
     *
     */

    public Date getResidentStartDate() {
        return this.residentStartDate;
    }

    public void setResidentStartDate(Date residentStartDate) {
        this.residentStartDate = residentStartDate;
    }
    /**
     *      *            @hibernate.property
     *             column="citizen"
     *             length="1"
     *
     */

    public Boolean getCitizen() {
        return this.citizen;
    }

    public void setCitizen(Boolean citizen) {
        this.citizen = citizen;
    }
    /**
     *      *            @hibernate.property
     *             column="updated_by"
     *             length="100"
     *
     */

    public String getUpdatedBy() {
        return this.updatedBy;
    }

    public void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }
    /**
     *      *            @hibernate.property
     *             column="person_status"
     *             length="20"
     *
     */

    public String getPersonStatus() {
        return StringUtils.isBlank(this.personStatus) ? "Active" : this.personStatus ;
    }

    public void setPersonStatus(String personStatus) {
        this.personStatus = personStatus;
    }
    /**
     *      *            @hibernate.property
     *             column="employer_name"
     *             length="100"
     *
     */

    public String getEmployerName() {
        return this.employerName;
    }

    public void setEmployerName(String employerName) {
        this.employerName = employerName;
    }
    /**
     *      *            @hibernate.property
     *             column="primary_person"
     *             length="1"
     *
     */

    public Boolean getPrimaryPerson() {
        return this.primaryPerson;
    }

    public void setPrimaryPerson(Boolean primaryPerson) {
        this.primaryPerson = primaryPerson;
    }
    /**
     *      *            @hibernate.property
     *             column="date_of_birth"
     *             length="10"
     *
     */

    public Date getDateOfBirth() {
        return this.dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }
    /**
     *      *            @hibernate.property
     *             column="version"
     *             length="10"
     *
     */

    public Integer getVersion() {
        return this.version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

	/**
     *            @hibernate.set
     *             lazy="true"
     *             table="person_access_group"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.many-to-many
     *             column="access_group_id"
     *             class="org.icnmasjid.member.model.AccessGroup"
     *
     */
    public Set<AccessGroup> getAccessGroups() {
    	return accessGroups;
    }

    public void setAccessGroups(Set<AccessGroup> ags) {
    	accessGroups = ags;
    }

	public Address getSearchAddress() {
		return searchAddress;
	}

	public void setSearchAddress(Address searchAddress) {
		this.searchAddress = searchAddress;
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((email == null) ? 0 : email.hashCode());
		result = PRIME * result + ((firstName == null) ? 0 : firstName.hashCode());
		result = PRIME * result + ((lastName == null) ? 0 : lastName.hashCode());
		result = PRIME * result + ((personId == null) ? 0 : personId.hashCode());
		result = PRIME * result + ((phoneHome == null) ? 0 : phoneHome.hashCode());
		result = PRIME * result + ((version == null) ? 0 : version.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Person other = (Person) obj;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		if (personId == null) {
			if (other.personId != null)
				return false;
		} else if (!personId.equals(other.personId))
			return false;
		if (phoneHome == null) {
			if (other.phoneHome != null)
				return false;
		} else if (!phoneHome.equals(other.phoneHome))
			return false;
		if (version == null) {
			if (other.version != null)
				return false;
		} else if (!version.equals(other.version))
			return false;
		return true;
	}

	public List<Address> getAddressList() {
		return addressList;
	}

	public void setAddressList(List<Address> addressList) {
		this.addressList = addressList;
	}

	public boolean isSearchPrimary() {
		return searchPrimary;
	}

	public void setSearchPrimary(boolean searchPrimary) {
		this.searchPrimary = searchPrimary;
	}

    /**
     *	@hibernate.property
     *             column="source_id"
     *
     */
	public Integer getSourceId() {
		return sourceId;
	}

	public void setSourceId(Integer sourceId) {
		this.sourceId = sourceId;
	}

    /**
     *	@hibernate.property
     *             column="source_type"
     *
     */
	public String getSourceType() {
		return sourceType;
	}

	public void setSourceType(String sourceType) {
		this.sourceType = sourceType;
	}

	public void addAddress(Address a) {
		getAddresses().add(a);
		a.addPerson(this);
	}

    /**
     *            @hibernate.set
     *             lazy="true"
     *             cascade="all-delete-orphan"
     *             inverse="true"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.one-to-many
     *             	class="org.icnmasjid.member.model.MemberInformation"
     *
     *
     */
	public Set<MemberInformation> getMemberInformations() {
		return memberInformations;
	}

	public void setMemberInformations(Set<MemberInformation> memberInformations) {
		this.memberInformations = memberInformations;
	}

    /**
     *            @hibernate.set
     *             lazy="true"
     *             cascade="all-delete-orphan"
     *             inverse="true"
     *            @hibernate.key
     *             column="person_id"
     *             not-null="true"
     *            @hibernate.one-to-many
     *             	class="org.icnmasjid.member.model.PersonPayment"
     *
     *
     */
	public Set<PersonPayment> getPersonPayments() {
		return personPayments;
	}

	public void setPersonPayments(Set<PersonPayment> personPayments) {
		this.personPayments = personPayments;
	}
	
	public List<PersonPayment> getPersonPaymentsList() {
		return new ArrayList<PersonPayment>(getPersonPayments());
	}

    /**
     *	@hibernate.property
     *             column="notes"
     *
     */
	public String getNotes() {
		return notes;
	}

	public void setNotes(String notes) {
		this.notes = notes;
	}
    /**
     *	@hibernate.property
     *             column="verified_date"
     *
     */
	public Date getVerifiedDate() {
		return verifiedDate;
	}

	public void setVerifiedDate(Date verifiedDate) {
		this.verifiedDate = verifiedDate;
	}

	public boolean isVerified() {
		return false;
	}

	public void setVerified(boolean verified) {
		if ( verified ) {
			setVerifiedDate(new Date(System.currentTimeMillis()));
		} else {
			setVerifiedDate(null);
		}
	}

	public boolean isMember(int year) {
		for ( MemberInformation mi : getMemberInformations() ) {
			if (mi.getYearOfMembership() == year ) {
				return true;
			}
		}
		return false;
	}

	public void setMember(boolean member, int year) {
		if (member) {
			if ( !isMember(year) ) {
				MemberInformation newMi = new MemberInformation(year);
				newMi.setPerson(this);
				getMemberInformations().add(newMi);
			}
		} else {
			if ( isMember(year) ) {
				MemberInformation mi = null;
				for ( MemberInformation m : getMemberInformations() ) {
					if (m.getYearOfMembership() == year ) {
						mi = m;
					}
				}
				getMemberInformations().remove(mi);
			}
		}

	}

	public boolean isSearchVerified() {
		return searchVerified;
	}

	public void setSearchVerified(boolean searchVerified) {
		this.searchVerified = searchVerified;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public SubOrg getSubOrg() {
		return subOrg;
	}

	public void setSubOrg(SubOrg subOrg) {
		this.subOrg = subOrg;
	}

	public PersonPayment getPersonPayment() {
		return personPayment;
	}

	public void setPersonPayment(PersonPayment personPayment) {
		this.personPayment = personPayment;
	}
    /**
     *	@hibernate.property
     *             column="user_updated"
     *
     */
	public Integer getUserUpdated() {
		return userUpdated;
	}

	public void setUserUpdated(Integer userUpdated) {
		this.userUpdated = userUpdated;
	}
    /**
     *	@hibernate.property
     *             column="user_viewed"
     *
     */
	public Integer getUserViewed() {
		return userViewed;
	}

	public void setUserViewed(Integer userViewed) {
		this.userViewed = userViewed;
	}

    /**
     *	@hibernate.property
     *             column="email_sent"
     *
     */
	public Timestamp getEmailSent() {
		return emailSent;
	}

	public void setEmailSent(Timestamp emailSent) {
		this.emailSent = emailSent;
	}

	/**
     *	@hibernate.property
     *             column="opt_in_text_messages"
     *
     */
	public Boolean getOptInForTextMessages() {
		return optInForTextMessages;
	}

	public void setOptInForTextMessages(Boolean optInForTextMessages) {
		this.optInForTextMessages = optInForTextMessages;
	}

	/**
	 * I return all the roles for this person
	 * @return
	 */
	public String getRoles() {
		StringBuffer roles = new StringBuffer();
		for ( PersonSubOrgRole psor: getPersonSubOrgRoles() ) {
			roles.append(psor.getSubOrg().getName());
			roles.append("-");
			roles.append(psor.getRole().getName());
		}
		return roles.toString();
	}


	public Boolean getFeesPaid() {
		String pc = "WeekendSchoolFees2008";
		switch(getNumberOfStudents()) {
			case	1:
				return getTotalFees(pc) >= 250;
			case	2:
				return getTotalFees(pc) >= 450;
			case	3:
				return getTotalFees(pc) >= 650;
			case 	4:
				return getTotalFees(pc) >= 650;
			default:
				return false;
		}
	}

	public Boolean getLunchPaid() {
		String pc = "WeekendSchoolFees2008";
		if ( getFeesPaid() ) {
			switch(getNumberOfStudents()) {
				case	1:
					return getTotalFees(pc) >= 310;
				case	2:
					return getTotalFees(pc) >= 570;
				case	3:
					return getTotalFees(pc) >= 830;
				case 	4:
					return getTotalFees(pc) >= 890;
				default:
					return false;
			}
		}
		return false;
	}

	public Boolean getBooksPaid() {
		String pc = "WeekendSchoolFees2008";
		if ( getFeesPaid() ) {
			if ( getLunchPaid() ) {
				switch(getNumberOfStudents()) {
					case	1:
						return getTotalFees(pc) >= 350;
					case	2:
						return getTotalFees(pc) >= 650;
					case	3:
						return getTotalFees(pc) >= 950;
					case 	4:
						return getTotalFees(pc) >= 1050;
					default:
						return false;
				}
			} else {
				switch(getNumberOfStudents()) {
					case	1:
						return getTotalFees(pc) >= 290;
					case	2:
						return getTotalFees(pc) >= 530;
					case	3:
						return getTotalFees(pc) >= 770;
					case 	4:
						return getTotalFees(pc) >= 810;
					default:
						return false;
				}
			}
		}
		return false;

	}

	public Double getTotalFees(String pc) {
		Person parentPerson = getParent();
		if ( parentPerson == null ) {
			parentPerson = this;
		}
		double tf = 0;
		for ( PersonPayment pp: parentPerson.getPersonPayments() ) {
			if ( pp.getPaymentCategory().getName().equalsIgnoreCase(pc) ) {
				tf+= pp.getPaymentAmount();
			}
		}
		return tf;
	}

	public int getNumberOfStudents() {
		Person parentPerson = getParent();
		if ( parentPerson == null ) {
			parentPerson = this;
		}
		int count = 0;
		for ( PersonRelation pr: parentPerson.getPersonRelations() ) {
			if ( pr.getRelatedPerson().isWSStudent() ) {
				count++;
			}
		}
		return count;
	}

	public boolean isWSStudent() {
		for ( PersonSubOrgRole psor: getPersonSubOrgRoles() ) {
			if ( psor.getRole().getName().startsWith("Student")) {
				return true;
			}
		}
		return false;
	}
	
	public boolean isWSStudent(String year) {
		for ( PersonSubOrgRole psor: getPersonSubOrgRoles() ) {
			if ( psor.getRole().getName().equalsIgnoreCase("Student-" + year) ) {
				return true;
			}
		}
		return false;
	}
	

	public Person getParent() {
		Person parentPerson = null;
		for ( PersonRelation pr : getParentPersonRelations() ) {
			parentPerson = pr.getPerson();
		}
		return parentPerson;
	}

	public String getParentNotes() {
		Person p = getParent();
		if ( p != null ) {
			return p.getNotes();
		}
		return "";
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
				.append("userUpdated", this.userUpdated).append("personId", this.personId)
				.append("email", this.email)
				.append("gender",this.gender)
				.append("updatedBy", this.updatedBy).append("lastName",
						this.lastName)
				.append("personStatus", this.personStatus)
				.append("verified", this.isVerified())
				.append("createdDate", this.createdDate).append("residentStartDate",
						this.residentStartDate).append("phoneHome",
						this.phoneHome).append("feesPaid",
						this.getFeesPaid()).append("phoneFax", this.phoneFax)
				.append("phoneMobile", this.phoneMobile).append("dateOfBirth", this.dateOfBirth)
				.append("optInForTextMessages",
						this.optInForTextMessages).append("sourceType",
						this.sourceType)
				.append("emailSent", this.emailSent).append("phoneWork",
						this.phoneWork).append("firstName", this.firstName)
				.append("email2", this.email2).append("citizen", this.citizen)
				.append("version", this.version).append("userViewed",
						this.userViewed).append("sourceId",
						this.sourceId).toString();
	}

	public List<Integer> getMemberYear() {
		if ( memberYear == null ) {
			memberYear = new ArrayList<Integer>();
		}
		return memberYear;
	}

	public void setMemberYear(List<Integer> memberYear) {
		this.memberYear = memberYear;
	}

	public Integer getSearchMemberYear() {
		return searchMemberYear;
	}

	public void setSearchMemberYear(Integer searchMemberYear) {
		this.searchMemberYear = searchMemberYear;
	}
	
	public Double getPaymentAmount(String paymentCategory) {
		double payment = 0;
		for ( PersonPayment pp: getPersonPayments() ) {
			if ( pp.getPaymentCategory().getName().equalsIgnoreCase(paymentCategory)) {
				payment += pp.getPaymentAmount();
			}
		}
		return payment;
	}
	
	public Double getBalance(String year) {
		int numberOfStudents = getStudents("Student-"+year).size();
		List<String> credits =
				Arrays.asList(
					new String[]{
						"Payment_Plan_" + year,
						"TeacherDiscount" + year,
						"WeekendSchoolFees" + year,
						"FinancialHelp" + year,
						"FamilyDiscount" + year,
						"Discount" + year,
					}
				);
		List<String> debits = Arrays.asList(new String[]{"RefundWSFees"+year});
		double payment = 0.0;
		for ( PersonPayment pp: getPersonPayments() ) {
			if ( credits.contains(pp.getPaymentCategory().getName())) {
				payment += pp.getPaymentAmount();
			}
			if ( debits.contains(pp.getPaymentCategory().getName())) {
				payment -= pp.getPaymentAmount();
			}
		}
		
		switch (numberOfStudents) {
			case 0:
				return 0.0;
			case 1:
				return 395.00 - payment;
			case 2:
				return 740.00 - payment;
			default:
				return 1000.00 - payment;
			
		}
	}
	
	public List<Person> getStudents(String year) {
		List<Person> students = new ArrayList<Person>();
		for (PersonRelation pr: getPersonRelations() ) {
			if ( pr.getRelationshipType().getRelationshipType().equalsIgnoreCase("child") ) {
				if ( pr.getRelatedPerson().isStudent(year) ) {
					students.add(pr.getRelatedPerson());
				}
			}
		}
		return students;
	}
	
	private boolean isStudent(String year) {
		for ( PersonSubOrgRole psor: getPersonSubOrgRoles() ) {
			if ( psor.getRole().getName().equalsIgnoreCase(year)) {
				return true;
			}
		}
		return false;
	}

	public String getGrade(String year) {
		StringBuffer sb = new StringBuffer();
		for ( PersonSubOrgRole psor: getPersonSubOrgRoles() ) {
			if ( psor.getRole().getName().equalsIgnoreCase(year)) {
				sb.append(psor.getSubOrg().getName());
				sb.append(",");
			}
		}
		if ( sb.toString().length() > 0) {
			return sb.toString().substring(0, sb.length()-1);
		}
		return null;
	}
	
	public SubOrg getSubOrg(String roleName) {
		for ( PersonSubOrgRole psor: getPersonSubOrgRoles() ) {
			if ( psor.getRole().getName().equalsIgnoreCase(roleName)) {
				return psor.getSubOrg();
			}
		}
		return null;
	}
	
	
	public List<String> getEmails() {
		List<String> emails = new ArrayList<String>();
		if ( StringUtils.isNotEmpty(getEmail())) {
			emails.add(getEmail());
		}
		if ( StringUtils.isNotEmpty(getEmail2())) {
			emails.add(getEmail2());
		}
		Person spouse = getSpouse();
		if ( spouse != null ) {
			if ( StringUtils.isNotEmpty(spouse.getEmail())) {
				emails.add(spouse.getEmail());
			}
			if ( StringUtils.isNotEmpty(spouse.getEmail2())) {
				emails.add(spouse.getEmail2());
			}			
		}
		return emails;
	}
	
	public Person getSpouse() {
		for ( PersonRelation pr: getPersonRelations() ) {
			if ( pr.getRelationshipType().getRelationshipType().equalsIgnoreCase("spouse")) {
				return pr.getRelatedPerson();
			}
		}
		return null;
	}

	/**
     *	@hibernate.property
     *             column="allergies"
     *
     */	
	public String getAllergies() {
		return allergies;
	}

	public void setAllergies(String allergies) {
		this.allergies = allergies;
	}

	/**
     *	@hibernate.property
     *             column="registered_to_vote"
     *
     */	
	public Boolean getRegisteredToVote() {
		return registeredToVote;
	}

	public void setRegisteredToVote(Boolean registeredToVote) {
		this.registeredToVote = registeredToVote;
	}
	

	public void addOrUpdateChildren(SchoolRegistration sr) {
		// TODO Auto-generated method stub
		
	}
	
	public boolean isPrimaryPerson() {
		return getParent() == null;
	}

	/**
     *	@hibernate.property
     *             column="employer_matches_donation"
     *
     */		
	public Boolean getEmployerMatchesDonation() {
		return employerMatchesDonation;
	}

	public void setEmployerMatchesDonation(Boolean employerMatchesDonation) {
		this.employerMatchesDonation = employerMatchesDonation;
	}

	/**
     *	@hibernate.property
     *             column="comments"
     *
     */	
	public String getComments() {
		return comments;
	}

	public void setComments(String comments) {
		this.comments = comments;
	}

	public void addPersonPayment(
		double amount, 
		PaymentCategory pc,
		java.util.Date paymentDate,
		String refId
	) throws Exception {
		PersonPayment pp = new PersonPayment();
		pp.setPerson(this);
		pp.setPaymentAmount(amount);
		pp.setPaymentCategory(pc);
		pp.setPaymentDate(new java.sql.Date(paymentDate.getTime()));
		pp.setPaymentMethod(refId);
		getPersonPayments().add(pp);
	}

	public boolean hasUnregisteredStudents(String current, String previous) {
		for (PersonRelation pr: getPersonRelations() ) {
			if ( pr.getRelationshipType().getRelationshipType().equalsIgnoreCase("child") ) {
				if ( 
							pr.getRelatedPerson().isStudent(previous) 
						&& 	! pr.getRelatedPerson().isStudent(current) 
				) {
					return true;
				}
			}
		}
		return false;
	}

	/**
     *	@hibernate.property
     *             column="rfid"
     *
     */	
	public String getRfid() {
		return rfid;
	}

	public void setRfid(String rfid) {
		this.rfid = rfid;
	}
}
